/*
* $Id: QueenBeeTable.cpp 134 2010-08-26 11:32:19Z volok-aleksej@yandex.ru $
*
* Copyright 2009 by Volokitin Alexey
* All rights reserved
*
*/
#include "Common/include.h"
#include "QueenBeeTable.h"
#include "TableNames.h"
#include "../SqlBinder.h"
#include "Event/EventId.h"

CQueenBeeTable::CQueenBeeTable()
: CTable(QUEEN_BEE_TABLE_NAME){}
CQueenBeeTable::~CQueenBeeTable(){}

void CQueenBeeTable::CreateTable(IDatabase* pDatabase){
	std::tstring strRequest(_T("CREATE TABLE IF NOT EXISTS "));
	pDatabase->ExecRequest(strRequest + GetNameTable() + 
						_T("(id_queen_bee INTEGER NOT NULL,")\
						_T("name TEXT NOT NULL,")\
						_T("description TEXT NULL,")\
						_T("id_family INTEGER NULL,")\
						_T("id_parent_queen_bee INTEGER NULL,")\
						_T("date DATE NOT NULL,")\
						_T("breed INTEGER NULL,")\
						_T("fert TEXT NULL,")\
						_T("is_dead BOOL,")\
						_T("PRIMARY KEY(id_queen_bee ASC AUTOINCREMENT),")\
						_T("CONSTRAINT ftFamily")\
						_T("	FOREIGN KEY(id_family)")\
						_T("	REFERENCES family(id_family)")
						_T("	ON DELETE SET NULL,")\
						_T("CONSTRAINT ftQueenBee")\
						_T("	FOREIGN KEY(id_parent_queen_bee)")\
						_T("	REFERENCES queen_bee(id_queen_bee));"));
}
void CQueenBeeTable::UpdateValue(IDatabase* pDatabase){
	std::tstring strRequest(_T("UPDATE "));
	CSqlBinder binder(strRequest + GetNameTable() + 
		_T(" SET name=?, description=?, date=?, breed=?, ") + 
		_T("fert=?, is_dead=? WHERE id_queen_bee=?;"));
	binder.SetValue(0, m_content.s_strName);
	binder.SetValue(1, m_content.s_strDescription);
	binder.SetValue(2, m_content.s_date, true);
	binder.SetValue(3, (int)m_content.s_breed);
	binder.SetValue(4, m_content.s_strFert);
	binder.SetValue(5, m_content.s_bDead);
	binder.SetValue(6, m_content.s_nId);
	pDatabase->ExecRequest(binder.GetRequest());
	m_content.Clear();
	IApplication::GetApp()->GetEventManager()->SendEvent(QUEEN_BEE_DB_CHANGE_EVENT);
}
IResult* CQueenBeeTable::GetValue(IDatabase* pDatabase){
	CSqlBinder binder;
	std::tstring strRequest(_T("SELECT * FROM "));
	if(m_content.s_nId){
		binder.SetRequest(strRequest + GetNameTable() + _T(" WHERE id_queen_bee=?"));
		binder.SetValue(0, m_content.s_nId);
	}else if(m_content.s_nIdFamily){
		binder.SetRequest(strRequest + GetNameTable() + _T(" WHERE id_family=?"));
		binder.SetValue(0, m_content.s_nIdFamily);
	}else
		binder.SetRequest(strRequest + GetNameTable());
	m_content.Clear();
	return FillContent(pDatabase->ExecRequest(binder.GetRequest()));
}
void CQueenBeeTable::SetValue(IDatabase* pDatabase){
	CSqlBinder binder;
	std::tstring strRequest(_T("INSERT INTO "));
	binder.SetRequest(strRequest + GetNameTable() + 
		_T("(name, description, id_family, id_parent_queen_bee, date, breed, fert, is_dead) ")\
		_T("VALUES(?, ?, ?, ?, ?, ?, ?, ?)"));
	binder.SetValue(0, m_content.s_strName);
	binder.SetValue(1, m_content.s_strDescription);
	binder.SetValue(3, m_content.s_nIdParentQueenBee);
	binder.SetValue(4, m_content.s_date, true);
	binder.SetValue(5, (int)m_content.s_breed);
	binder.SetValue(6, m_content.s_strFert);
	binder.SetValue(7, m_content.s_bDead);
	binder.SetValue(2, m_content.s_nIdFamily);
	pDatabase->ExecRequest(binder.GetRequest());
	strRequest = _T("SELECT MAX(id_queen_bee) as id_queen_bee FROM ");
	MyTable table = pDatabase->ExecRequest(strRequest + GetNameTable());
	if(table.empty())
		m_content.s_nId = 0;
	else
		m_content.s_nId = _ttoi(table[0][0].m_strValueColumn.c_str());
	IApplication::GetApp()->GetEventManager()->SendEvent(QUEEN_BEE_DB_CHANGE_EVENT);
}
void CQueenBeeTable::DeleteValue(IDatabase* pDatabase){
	CSqlBinder binder;
	pDatabase->BeginTransaction(_T("DELETE_QUEEN_BEE"));
	std::tstring strRequest(_T("DELETE FROM "));
	if(m_content.s_nId){
		strRequest = strRequest + GetNameTable() + _T(" WHERE id_queen_bee=?");
		binder.SetValue(0, m_content.s_nId);
	}else if(!m_content.s_strName.empty()){
		strRequest = strRequest + GetNameTable() + _T(" WHERE name=?");
		binder.SetValue(0, m_content.s_strName);
	}else if(m_content.s_nIdFamily){
		strRequest = strRequest + GetNameTable() + _T(" WHERE id_family=?");
		binder.SetValue(0, m_content.s_nIdFamily);
	}else{
		strRequest = strRequest + GetNameTable();
	}
	binder.SetRequest(strRequest);
	pDatabase->ExecRequest(binder.GetRequest());
	strRequest = _T("UPDATE ");
	binder.SetRequest(strRequest + GetNameTable() + 
		_T(" SET id_parent_queen_bee=? WHERE id_parent_queen_bee=?;"));
	binder.ClearParameters();
	binder.SetValue(0, 0);
	binder.SetValue(1, m_content.s_nId);
	pDatabase->ExecRequest(binder.GetRequest());
	pDatabase->EndTransaction(_T("DELETE_QUEEN_BEE"));
	m_content.Clear();
	IApplication::GetApp()->GetEventManager()->SendEvent(QUEEN_BEE_DB_CHANGE_EVENT);
}
IOperation::i_content* CQueenBeeTable::CreateContent(){
	return new content;
}

void CQueenBeeTable::content::Clear(){
	s_nId = 0;
	s_strDescription.clear();
	s_date = 0;
	s_nIdParentQueenBee = 0;
	s_nIdFamily = 0;
	s_breed = HYBRID;
	s_bDead = false;
	s_strFert.clear();
}
void CQueenBeeTable::content::Set(const std::vector<CTableItem>& aContent){
	for(std::vector<CTableItem>::const_iterator it = aContent.begin(); it != aContent.end(); it++){
		if(it->m_strNameColumn == _T("date"))
			s_date = CConvertFunction::ConvertFromDate(it->m_strValueColumn);
		else if(it->m_strNameColumn == _T("id_family"))
			s_nIdFamily = _ttoi(it->m_strValueColumn.c_str());
		else if(it->m_strNameColumn == _T("id_queen_bee"))
			s_nId = _ttoi(it->m_strValueColumn.c_str());
		else if(it->m_strNameColumn == _T("description"))
			s_strDescription = it->m_strValueColumn;
		else if(it->m_strNameColumn == _T("name"))
			s_strName = it->m_strValueColumn;
		else if(it->m_strNameColumn == _T("breed"))
			s_breed = (breed)_ttoi(it->m_strValueColumn.c_str());
		else if(it->m_strNameColumn == _T("id_parent_queen_bee"))
			s_nIdParentQueenBee = _ttoi(it->m_strValueColumn.c_str());
		else if(it->m_strNameColumn == _T("fert"))
			s_strFert = it->m_strValueColumn;
		else if(it->m_strNameColumn == _T("is_dead"))
			s_bDead = _ttoi(it->m_strValueColumn.c_str());
	}
}
void CQueenBeeTable::content::Free(){
	delete this;
}

CQueenBeeTable::content::content(){
	Clear();
}
